Skip to content

fix(ai-isolate-cloudflare): accumulate toolResults across rounds#524

Merged
tombeckenham merged 3 commits intoTanStack:mainfrom
Sriketk:fix/ai-isolate-cloudflare-accumulate-tool-results
May 8, 2026
Merged

fix(ai-isolate-cloudflare): accumulate toolResults across rounds#524
tombeckenham merged 3 commits intoTanStack:mainfrom
Sriketk:fix/ai-isolate-cloudflare-accumulate-tool-results

Conversation

@Sriketk
Copy link
Copy Markdown
Contributor

@Sriketk Sriketk commented May 3, 2026

Summary

The Cloudflare isolate driver wipes toolResults between need_tools rounds (packages/typescript/ai-isolate-cloudflare/src/isolate-driver.ts:178). wrap-code uses sequential tc_<idx> ids that are re-derived from scratch every time the Worker re-executes user code, so prior-round results must stay in the cache. With the wipe, multi-tool programs like:

const x = await A();
const y = await B();
return x + y;

ping-pong between {tc_0} and {tc_1}:

round sent toolResults worker reaction
1 (none) throws on tc_0
2 {tc_0} tc_0 cached → throws on tc_1
3 {tc_1} (pre-fix) tc_0 missing → throws on tc_0 again
4 {tc_0} tc_1 missing → throws on tc_1 again
... ... until MaxRoundsExceeded

Single-tool code worked because only one cache entry was ever needed in a given round.

Fix

One-line change: toolResults = {}toolResults = { ...(toolResults ?? {}) }. Within an execute() call's round loop only — toolResults is local to execute(), so each new execute() still starts fresh (independent code, independent ids).

Why this slipped through

Existing isolate-driver.test.ts cases:

  • All need_tools cases are single-round (need_tools → done).
  • IDs in tests use ad-hoc shapes like add_1, getA_1 — never wrap-code's real tc_<idx> format. The end-to-end contract between driver and wrap-code was never validated.
  • The MaxRoundsExceeded test loops the same tool, so doesn't exercise the multi-tool ping-pong.

Test plan

Adds accumulates toolResults across rounds for sequential tool calls to tests/isolate-driver.test.ts. Uses tc_<idx>-shaped ids matching wrap-code and asserts round 3 carries both tc_0 and tc_1.

  • New test fails on prior implementation (expected {success:true, value:'a'}, received undefined for tc_0 in round 3)
  • All 16 driver tests pass with the fix (pnpm vitest run tests/isolate-driver.test.ts)
  • Live repro against deployed Worker (cobalt-sandbox.sriketk5.workers.dev) confirms multi-tool code converges in 3 rounds post-fix

Related

Discovered while running multi-tool code through @tanstack/ai-isolate-cloudflare@0.1.8 from a Cobalt MCP integration. Independent of #523 (which ports the worker from unsafe_eval to worker_loader); this fix touches isolate-driver.ts only and applies to both the legacy and ported binding paths.

Summary by CodeRabbit

  • Bug Fixes

    • Fixed Cloudflare isolate driver behavior to preserve tool results across successive execution rounds, preventing premature round exhaustion and execution failures in multi-tool workflows (e.g., alternating cache entries and max-round errors).
  • Tests

    • Added a regression test that simulates sequential tool calls to verify tool results are accumulated and retained across multiple rounds.

The Cloudflare isolate driver wiped toolResults between need_tools rounds.
wrap-code uses sequential tc_<idx> ids that are re-derived from scratch
every time the Worker re-executes user code, so prior-round results must
remain in the cache. With the wipe, multi-tool programs (e.g.
`await A(); await B();`) ping-pong between {tc_0} and {tc_1} and exhaust
maxToolRounds, surfacing as MaxRoundsExceeded.

Single-tool code worked because only one cache entry was ever needed in a
given round. Existing tests covered single-round flows only and used
ad-hoc tool-call ids rather than wrap-code's real tc_<idx> shape, so the
regression slipped through.

Adds a tc_<idx>-shaped regression test covering two sequential tool
calls. The test fails on the prior implementation and passes after the
one-line fix.
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 3, 2026

Review Change Stack
No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a07e9f0-a538-4219-a4e7-65a136eb5ef4

📥 Commits

Reviewing files that changed from the base of the PR and between 5fd3edc and bcb2f9c.

📒 Files selected for processing (1)
  • packages/typescript/ai-isolate-cloudflare/tests/isolate-driver.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/typescript/ai-isolate-cloudflare/tests/isolate-driver.test.ts

📝 Walkthrough

Walkthrough

The Cloudflare isolate driver now accumulates prior-round toolResults between worker round-trips instead of resetting them; a new Vitest regression test verifies sequential multi-tool rounds preserve tc_0 and tc_1 results and complete successfully.

Changes

Tool Results Accumulation Fix

Layer / File(s) Summary
Core Logic Fix
packages/typescript/ai-isolate-cloudflare/src/isolate-driver.ts
In CloudflareIsolateContext.execute, toolResults is now carried forward across rounds by cloning prior results instead of resetting to {} each iteration. Inline comments explain why sequential tc_<idx> tool IDs require result retention.
Regression Test
packages/typescript/ai-isolate-cloudflare/tests/isolate-driver.test.ts
New test case accumulates toolResults across rounds for sequential tool calls verifies that toolResults from tc_0 and tc_1 are both present in the final request POST body after three worker rounds.
Changelog
.changeset/accumulate-tool-results.md
Patch release entry documents the toolResults accumulation fix and notes the new end-to-end regression test covering previously missing multi-tool behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Worker
  participant Driver
  Client->>Worker: initial execute
  Worker-->>Client: need_tools (tc_0)
  Client->>Driver: run tool tc_0
  Driver-->>Client: toolResults {tc_0}
  Client->>Worker: continue with toolResults
  Worker-->>Client: need_tools (tc_1)
  Client->>Driver: run tool tc_1 (retain tc_0)
  Driver-->>Client: toolResults {tc_0,tc_1}
  Client->>Worker: final continue -> done
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰
I hop through rounds where tools once slipped away,
tc_0 and tc_1 together now stay.
No more lost answers across worker flights,
Cache holds the traces through day and night.
Hooray — the rabbit grins at stable runs today.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description includes a detailed explanation of the problem, the fix, test plan, and verification, but does not follow the required template structure with the specified sections and checklist items. Restructure the description to follow the template: include a concise 'Changes' section, add the 'Checklist' with the two items marked as completed, and include the 'Release Impact' section confirming the changeset was generated.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely summarizes the main change: fixing the driver to accumulate toolResults across rounds instead of wiping them.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link
Copy Markdown

nx-cloud Bot commented May 7, 2026

View your CI Pipeline Execution ↗ for commit bcb2f9c

Command Status Duration Result
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 4s View ↗

☁️ Nx Cloud last updated this comment at 2026-05-08 04:20:50 UTC

@pkg-pr-new
Copy link
Copy Markdown

pkg-pr-new Bot commented May 7, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/@tanstack/ai@524

@tanstack/ai-anthropic

npm i https://pkg.pr.new/@tanstack/ai-anthropic@524

@tanstack/ai-client

npm i https://pkg.pr.new/@tanstack/ai-client@524

@tanstack/ai-code-mode

npm i https://pkg.pr.new/@tanstack/ai-code-mode@524

@tanstack/ai-code-mode-skills

npm i https://pkg.pr.new/@tanstack/ai-code-mode-skills@524

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/@tanstack/ai-devtools-core@524

@tanstack/ai-elevenlabs

npm i https://pkg.pr.new/@tanstack/ai-elevenlabs@524

@tanstack/ai-event-client

npm i https://pkg.pr.new/@tanstack/ai-event-client@524

@tanstack/ai-fal

npm i https://pkg.pr.new/@tanstack/ai-fal@524

@tanstack/ai-gemini

npm i https://pkg.pr.new/@tanstack/ai-gemini@524

@tanstack/ai-grok

npm i https://pkg.pr.new/@tanstack/ai-grok@524

@tanstack/ai-groq

npm i https://pkg.pr.new/@tanstack/ai-groq@524

@tanstack/ai-isolate-cloudflare

npm i https://pkg.pr.new/@tanstack/ai-isolate-cloudflare@524

@tanstack/ai-isolate-node

npm i https://pkg.pr.new/@tanstack/ai-isolate-node@524

@tanstack/ai-isolate-quickjs

npm i https://pkg.pr.new/@tanstack/ai-isolate-quickjs@524

@tanstack/ai-ollama

npm i https://pkg.pr.new/@tanstack/ai-ollama@524

@tanstack/ai-openai

npm i https://pkg.pr.new/@tanstack/ai-openai@524

@tanstack/ai-openrouter

npm i https://pkg.pr.new/@tanstack/ai-openrouter@524

@tanstack/ai-preact

npm i https://pkg.pr.new/@tanstack/ai-preact@524

@tanstack/ai-react

npm i https://pkg.pr.new/@tanstack/ai-react@524

@tanstack/ai-react-ui

npm i https://pkg.pr.new/@tanstack/ai-react-ui@524

@tanstack/ai-solid

npm i https://pkg.pr.new/@tanstack/ai-solid@524

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/@tanstack/ai-solid-ui@524

@tanstack/ai-svelte

npm i https://pkg.pr.new/@tanstack/ai-svelte@524

@tanstack/ai-vue

npm i https://pkg.pr.new/@tanstack/ai-vue@524

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/@tanstack/ai-vue-ui@524

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/@tanstack/preact-ai-devtools@524

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/@tanstack/react-ai-devtools@524

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/@tanstack/solid-ai-devtools@524

commit: bcb2f9c

@tombeckenham tombeckenham merged commit d6a2588 into TanStack:main May 8, 2026
8 checks passed
@github-actions github-actions Bot mentioned this pull request May 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants